package com.usooft.metaTalent.core.system.service.base;

import com.usooft.framework.core.query.Limit;
import com.usooft.framework.core.query.Page;
import com.usooft.metaTalent.core.system.entity.SearchTerm;
import com.usooft.metaTalent.core.system.mapper.SearchTermMapper;
import com.usooft.metaTalent.core.system.query.SearchTermQuery;
import com.usooft.metaTalent.core.system.service.SearchTermService;
import com.usooft.metaTalent.core.system.wrapper.SearchTermWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.lang.NonNull;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;

public abstract class BaseSearchTermService implements SearchTermService {
    @Autowired
    private SearchTermMapper searchTermMapper;

    @Override
    public SearchTerm get(@NonNull Long id) {
        return find(id).orElseThrow();
    }

    @Override
    public Optional<SearchTerm> find(@NonNull Long id) {
        return Optional.ofNullable(searchTermMapper.get(id));
    }

    @Override
    public List<SearchTermWrapper> list(SearchTermQuery query) {
        return searchTermMapper.list(query);
    }

    @Override
    public Page<SearchTermWrapper> page(SearchTermQuery query) {
        int rows = searchTermMapper.count(query.getFilter());
        return new Page<>(rows, rows == 0 ? new ArrayList<>() : searchTermMapper.list(query));
    }

    protected Optional<SearchTerm> findOne(SearchTermQuery.Filter filter,
            SearchTermQuery.Sorts sorts) {
        List<SearchTermWrapper> wrappers = list(SearchTermQuery.builder()
                                .filter(filter)
                                .sorts(sorts)
                                .limit(Limit.rowCount(1))
                                .build());
        return wrappers.stream().findFirst().map(Function.identity());
    }

    protected Optional<SearchTerm> findOne(SearchTermQuery.Filter filter) {
        return findOne(filter, SearchTermQuery.Sorts.builder().build());
    }

    @Override
    public int count(SearchTermQuery.Filter filter) {
        return searchTermMapper.count(filter);
    }

    protected SearchTerm internalAdd(String content, Boolean isHot, SearchTerm.PortType portType,
            SearchTerm.Position position, Boolean isTop, Integer sort) {
        SearchTerm searchTerm = new SearchTerm();
        searchTerm.setContent(content);
        searchTerm.setIsHot(isHot);
        searchTerm.setPortType(portType);
        searchTerm.setPosition(position);
        searchTerm.setIsTop(isTop);
        searchTerm.setSort(sort);

        searchTerm.setCreatedDate(LocalDateTime.now());
        searchTerm.setVersion(0);
        searchTerm.setIsDelete(false);
        searchTermMapper.add(searchTerm);
        return searchTerm;
    }

    protected void internalUpdate(@NonNull SearchTerm searchTerm) {
        searchTerm.setLastModifiedDate(LocalDateTime.now());

        int rows = searchTermMapper.update(searchTerm);
        if (rows == 0) {
            throw new OptimisticLockingFailureException("更新失败。可能搜索词条 (" + searchTerm.getId() + ") 的版本 (" + searchTerm.getVersion() + ") 已不是最新");
        }
        searchTerm.setVersion(searchTerm.getVersion() + 1);
    }
}
